// Prevents additional console window on Windows in release, DO NOT REMOVE!!
#![cfg_attr(not(debug_assertions), windows_subsystem = "windows")]

use headless_chrome::Browser;
use regex::Regex;
use reqwest::blocking::Client;
use std::fs::File;
use std::hash::DefaultHasher;
use std::io::Write;
use std::hash::{Hash, Hasher};
use std::fs;
use std::thread;


#[tauri::command]
async fn greet(website:&str, dir_value:&str) -> Result<String, String> {
      // 检查是否是允许的网站
      if !website.starts_with("https://smartstore.naver.com") && 
      !website.starts_with("https://shopping.naver.com") {
       return Err("不支持爬取站点. 仅支持: smartstore.naver.com, shopping.naver.com".into());
   }
   let website_type = if website.starts_with("https://smartstore.naver.com") {
    1
    } else  {
        2
    }; 

    let product_number = extract_product_number(website);
    let number;
    if let Some(n) = &product_number {
        number = n;
    } else {
        return Err("网址异常未查询到产品编码".to_string());
    }

    let browser = Browser::default().map_err(|err| err.to_string())?; 
    let tab = browser.new_tab().map_err(|err| err.to_string())?;
    tab.navigate_to(website).map_err(|err| err.to_string())?;
    tab.wait_for_element(".se-image-resource").map_err(|err| err.to_string())?;
    tab.wait_until_navigated().map_err(|err| err.to_string())?;
    let body = tab.get_content().map_err(|err| err.to_string())?;
    let processed_elements = process_elements(body, website_type);
    let json_result = serde_json::to_string(&processed_elements).map_err(|err| err.to_string())?;

    // 启动一个异步任务来执行下载操作，但不等待其完成
    // 克隆参数到闭包中
    let dir_value_cloned = dir_value.to_string();
    let number_cloned = number.clone();
    thread::spawn(move || {
        download(processed_elements, &format!("{}/{}", dir_value_cloned, number_cloned))
    });
    Ok(json_result)
}


fn main() {
    tauri::Builder::default()
        .invoke_handler(tauri::generate_handler![greet])
        .run(tauri::generate_context!())
        .expect("error while running tauri application");
}

fn extract_product_number(website: &str) -> Option<String> {
    // 创建正则表达式对象
    let re = Regex::new(r"/(\d+)(\?|$)").unwrap();
    let mut product_number: Option<String> = None;

    // 在网址中查找匹配的部分
    if let Some(captures) = re.captures(website) {
        // 获取匹配到的数字部分
        if let Some(last_segment) = captures.get(1) {
            product_number = Some(last_segment.as_str().to_string());
        }
    }
    product_number
}

fn process_elements(body: String, website_type: i32) -> ProcessedElement {
    let document = scraper::Html::parse_document(body.as_str());
    let main_elements_selector = if website_type == 1 {
        "img.bd_1Niq0"
    } else {
        ".PViT63twHN img"
    };
    let mian_src_selector = scraper::Selector::parse(main_elements_selector).unwrap();
    let detail_src_selector = scraper::Selector::parse("img.se-image-resource").unwrap();
    let comment_src_selector = scraper::Selector::parse("._3E-ZOVR8K-").unwrap();
    let mut processed_element = ProcessedElement {
        main_src: Vec::new(),
        detail_src: Vec::new(),
        comment_src: Vec::new(),
    };
        
    for element in document.select(&mian_src_selector) {
        if let Some(src) = element.value().attr("src").map(|s| s.to_string()) {
            if let Some(index) = src.find('?') {
                let trimmed_src = &src[..index];
                processed_element.main_src.push(trimmed_src.to_string());
            } else {
                processed_element.main_src.push(src.clone());

            }
        }
    }

    for element in document.select(&detail_src_selector) {
        if let Some(src) = element.value().attr("data-src").map(|s| s.to_string()) {
            if let Some(index) = src.find('?') {
                let trimmed_src = &src[..index];
                processed_element.detail_src.push(trimmed_src.to_string());
            } else {
                processed_element.detail_src.push(src.clone());
            }
        }
    }

    for element in document.select(&comment_src_selector) {
        if let Some(src) = element.value().attr("data-src").map(|s| s.to_string()) {
            if let Some(index) = src.find('?') {
                let trimmed_src = &src[..index];
                processed_element.comment_src.push(trimmed_src.to_string());
            } else {
                processed_element.comment_src.push(src.clone());

            }
        }
    }
    
    processed_element
}

#[derive(Debug, serde::Serialize)] // 添加 Serialize trait 的派生属性
struct ProcessedElement {
    main_src: Vec<String>,
    detail_src: Vec<String>,
    comment_src: Vec<String>,
}

 fn download(processed_element: ProcessedElement, dir_value: &str) {
    let client = Client::new();
    // 遍历 main_src
    let main_directory = format!("{}{}", dir_value, "/main");
    mikdir(main_directory.as_str());
    for (_, url) in processed_element.main_src.iter().enumerate() {
        download_image(url, &client, main_directory.as_str());
    }

   
    // 遍历 detail_src
    let detail_directory = format!("{}{}", dir_value, "/detail");
    mikdir(detail_directory.as_str());
    for (_, url) in processed_element.detail_src.iter().enumerate() {
        download_image(url, &client, detail_directory.as_str());
    }

    // 遍历 comment_src
    let comment_directory = format!("{}{}", dir_value, "/comment");
    mikdir(comment_directory.as_str());
    for (_, url) in processed_element.comment_src.iter().enumerate() {
        download_image(url, &client, comment_directory.as_str());
    }
}

fn download_image(url: &str, client: &reqwest::blocking::Client, dir_value: &str) {
    let response = client.get(url).send().unwrap();
     // 创建一个 DefaultHasher 实例
     let mut hasher = DefaultHasher::new();
     // 使用 Hasher 的 `write` 方法将字符串转换为哈希值
     url.hash(&mut hasher);
     // 从 hasher 中获取哈希值
     let hash_value = hasher.finish();
    if response.status().is_success() {
        let file_path = format!("{}/{}.jpg", dir_value, hash_value);
        let mut file = File::create(file_path).unwrap();
        let bytes = response.bytes().unwrap();
        file.write_all(&bytes).unwrap();
        // println!("图像已保存为 {}", url);
    } else {
        // println!("无法下载图像：{}，URL：{}", response.status(), url);
    }
}

fn mikdir(path: &str) {
    if let Err(e) = fs::create_dir_all(path) {
        // 处理创建目录失败的情况
        panic!("无法创建目录: {:?}", e);
    } else {
        // println!("目录已成功创建或已存在:detail");
    }
}

